using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Runtime.InteropServices;

#if ENABLE_WINMD_SUPPORT
using Windows.Media;
using Windows.Graphics.Imaging;
using Windows.Foundation;
using Windows.Media.Devices.Core;
using Windows.Perception.Spatial;
using Windows.Perception.Spatial.Preview;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.ApplicationModel.Core;
#endif


public class CameraManager : MonoBehaviour
{
#if ENABLE_WINMD_SUPPORT
    private Windows.Perception.Spatial.SpatialCoordinateSystem worldSpatialCoordinateSystem;
#endif

    public RGBCamera rGBCamera = null;
    void Awake()
    {
#if ENABLE_WINMD_SUPPORT
#if UNITY_2020_1_OR_NEWER // note: Unity 2021.2 and later not supported
        IntPtr WorldOriginPtr = UnityEngine.XR.WindowsMR.WindowsMREnvironment.OriginSpatialCoordinateSystem;
        worldSpatialCoordinateSystem = Marshal.GetObjectForIUnknown(WorldOriginPtr) as Windows.Perception.Spatial.SpatialCoordinateSystem;
#else
        IntPtr WorldOriginPtr = UnityEngine.XR.WSA.WorldManager.GetNativeISpatialCoordinateSystemPtr();
        worldSpatialCoordinateSystem = Marshal.GetObjectForIUnknown(WorldOriginPtr) as Windows.Perception.Spatial.SpatialCoordinateSystem;
#endif
#endif
    }

    //public async Task<System.Numerics.Matrix4x4> GetTranformFromWorld()
    //{
    //    System.Numerics.Matrix4x4 cameraToWorld = new System.Numerics.Matrix4x4();

    //    if (rGBCamera.IsCapturing)
    //    {
    //        MyFrame returnFrame = await rGBCamera.GetLatestFrame();
    //        #if ENABLE_WINMD_SUPPORT
    //                cameraToWorld = (System.Numerics.Matrix4x4)returnFrame.spatialCoordinateSystem.TryGetTransformTo(worldSpatialCoordinateSystem);
    //        #endif
    //    }

    //    return cameraToWorld;
    //}
    

    public async Task<bool> InitCamera()
    {
        if(rGBCamera == null) rGBCamera = new RGBCamera();

        bool FixFocusFlag = false;
        bool SetExposureCompensationFlag = false;
        bool SetExposureFlag = false;
        bool InitCameraFlag = false;

        try
        {

            await rGBCamera.InitializeMediaFrameReaderAsync();
            InitCameraFlag = true;
            await rGBCamera.AutoFocus();

            await Task.Run(async () =>
            {
                Thread.Sleep(200);
                FixFocusFlag = await rGBCamera.FixFocus(ConfigSet.FocusValue);
                Thread.Sleep(200);
                SetExposureCompensationFlag = await rGBCamera.SetExposureCompensation(ConfigSet.ExposureCompensation);
                Thread.Sleep(200);
                SetExposureFlag = await rGBCamera.SetExposureTime(ConfigSet.ExposureTime);
                Thread.Sleep(200);
            });
            Thread.Sleep(200);



            if (!(FixFocusFlag && SetExposureCompensationFlag && SetExposureFlag && InitCameraFlag))
            {
               return false;
            }
            else
            {
                return true;
            }
        }
        catch (Exception ex)
        {
            return false;
        }
    }

    public async void CloseCamera()
    {
        if (rGBCamera != null)
        {
            await rGBCamera.StopMediaFrameReaderAsync();
        }
    }
}
